The Stack

NoneDefinition

The stack is a region of memory used for temporary storage. It a LIFO structure. It is primarily used to manage function calls, local variables, saved registers, and return addresses.

To work with the stack we perform operation on rsp. The rsp register always points to the top of the stack and changes as data is pushed or popped. The other register that refers to stack related information is rbp. This marks the base for the current function’s stack frame.

Example

Given the following representation of the stack, determine the value of RAX based on each instruction that follows.

The asterisk indicates the top of the stack. Note that traditionally we say the stack grows downward, meaning it grows into smaller memory addresses. So the top is actually at the bottom when depicted with larger memory addresses higher up.

Value Addr Top Indicator
10 0x100
20 0x0F8
15 0x0F0
12 0x0E8 *
  1. mov rax, rsp

    Copies the address associated with the top of the stack (asterisk *) into rax. Thus, rax will hold 0x0E8.

  2. mov rax, [rsp]

    Dereferences the memory address held by rsp, thus gets the value in the stack. Therefore, rax will hold 12.

  3. mov rax, [rsp + 8]

    Since rsp holds the address at the top of this stack, this will dereference the address that is 8 bits past the top of the stack (that is, 1 byte after, thus the next memory address since memory is byte addressable). The next value in the stack is 15.

  4. mov rax, [rsp + 16]

    Gets the value at the memory address two memory locations down on the stack (16 bits). Thus 20.

  5. mov rax, [rsp + 24]

    Gets the value at the memory address three memory locations down on the stack (24 bits). Thus 10.

  6. add rsp, 8 then mov rax, [rsp]

    Moves the top of the stack 8 bits (i.e. pops one value off the top). Then stores the value associated with the new rsp address in rax. Thus 15.

Push Instruction

The push instruction pushes values onto the stack. It also results in subtracting 8 from the value stored in rsp.

Example

Push 20 and 15 to the stack given. A starting point is given using the first row.

Value Addr Top Indicator
10 0x100 *

First let’s push 20 onto the stack. Note that this results in a subtraction of 8 from rsp to give us a new value for rsp.

push 20  ; subtract 8 from current addr of rsp (move stack pointer)
         ; store new value of 20
         ; rsp = 0x100 - 8

The stack can now be represented as follows:

Value Addr Top Indicator
10 0x100
20 0x0F8 *

Now let’s push 15 onto the stack. Again, this results in a subtraction of 8 from rsp to give us a new value for rsp.

push 15 ; rsp = 0x0F8 - 8

The stack now appears as follows.

Value Addr Top Indicator
10 0x100
20 0x0F8
15 0x0F0 *

Pop Instruction

The pop instruction removes values from the stack into a designated register. It also results in adding 8 to the value stored in rsp.

Example

Given the representation of the stack shown, pop the top value of the give stack into rax.

Value Addr Top Indicator
10 0x100
20 0x0F8
15 0x0F0 *
pop rax

A representation of the stack after the pop operation follows.

Value Addr Top Indicator
10 0x100
20 0x0F8 *

Additionally, we have that rsp = 0x0F8 and rax=15.